package com.treasure.mall.biz.remote.wx.impl;

import com.treasure.mall.biz.config.wechat.WeChatConfig;
import com.treasure.mall.biz.entity.live.LiveRoomPO;
import com.treasure.mall.biz.entity.order.SubOrderPO;
import com.treasure.mall.biz.entity.user.WxSubscribeUser;
import com.treasure.mall.biz.remote.wx.WxTemplateMessageService;
import com.treasure.mall.biz.remote.wx.WxTemplateMessageType;
import com.treasure.mall.biz.remote.wx.ZbWxMpService;
import com.treasure.mall.biz.remote.wx.dto.DeliverTemplateDTO;
import com.treasure.mall.biz.remote.wx.dto.LiveTemplateDTO;
import com.treasure.mall.biz.remote.wx.dto.UserCreateOrderTemplateDTO;
import com.treasure.mall.biz.service.core.live.LiveRoomService;
import com.treasure.mall.biz.service.core.user.WxSubscribeUserService;
import com.treasure.mall.zbq.common.base.ApiResult;
import com.treasure.mall.zbq.common.base.ResultCodeEnum;
import com.treasure.mall.zbq.common.exception.ApiException;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpTemplateMsgService;
import me.chanjar.weixin.mp.api.impl.WxMpTemplateMsgServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * <p>
 * +---------------------------------------------------------
 * * @package: com.treasure.mall.biz.remote.wx.impl
 * * @author: guomw (guomwchen@foxmail.com)
 * * @date: 2020/8/26 9:40 下午
 * * @since: V1.0.0
 * +---------------------------------------------------------
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 * 
 */
@Service
public class WxTemplateMessageServiceImpl implements WxTemplateMessageService {
    @Autowired
    private WxSubscribeUserService wxSubscribeUserService;
    @Autowired
    private ZbWxMpService zbWxMpService;
    @Autowired
    private WeChatConfig weChatConfig;
    @Autowired
    private LiveRoomService liveRoomService;
    private static WxMpTemplateMsgService wxMpTemplateMsgService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public synchronized WxMpTemplateMsgService templateMsgService() {
        if (wxMpTemplateMsgService == null) {
            wxMpTemplateMsgService = new WxMpTemplateMsgServiceImpl(zbWxMpService.getService());
        }
        return wxMpTemplateMsgService;
    }

    /**
     * 支付成功通知
     *
     * @param orderPO
     */
    @Override
    public void sendPlaySuccessMessage(SubOrderPO orderPO) {
        try {
            WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUserId(orderPO.getOrderPO().getUserPO().getUserId());
            if (wxSubscribeUser == null) {
                return;
            }
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue("恭喜您，您已成功支付！");
            data.add(firstData);
            //商家名称
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(orderPO.getMerchantPO().getData().getTitle());
            data.add(keyword1);
            //交易金额
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(orderPO.getFinalAmount().doubleValue() + "元");
            data.add(keyword2);
            //交易时间
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            data.add(keyword3);
            //交易号
            WxMpTemplateData keyword4 = new WxMpTemplateData();
            keyword4.setName("keyword4");
            keyword4.setValue(orderPO.getSubOrderId());
            data.add(keyword4);


            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.PAYED_SUCCESS.getDesc())
                    .toUser(wxSubscribeUser.getOpenId())
                    .data(data)
                    .miniProgram(getMiniProgram())
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);


            //给商家发送有人下单提示通知
            createOrderSuccessMessage(UserCreateOrderTemplateDTO.builder()
                    .userId(orderPO.getMerchantPO().getUser().getUserId())
                    .createTime(orderPO.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")))
                    .receivingInfo(orderPO.getOrderPO().getReceivingInfo())
                    .orderId(orderPO.getSubOrderId())
                    .build());


        } catch (Exception ignored) {

        }
    }


    @Override
    public void sendLiveRoomMessage(LiveTemplateDTO liveTemplateDTO) {
        List<WxSubscribeUser> list = wxSubscribeUserService.findAll();
        if (list == null || list.size() == 0) {
            return;
        }
        this.sendLiveMessage(list, liveTemplateDTO);
    }

    /**
     * 给指定用户发送直播间通知
     *
     * @param userId          指定用户ID
     * @param liveTemplateDTO 发送消息的模板
     */
    @Override
    public void sendUserByLiveRoomMessage(Long userId, LiveTemplateDTO liveTemplateDTO) {
        WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUserId(userId);
        if (wxSubscribeUser != null) {
            this.switchSend(liveTemplateDTO, wxSubscribeUser);
        } else {
            throw new ApiException(ApiResult.error(ResultCodeEnum.ERROR, "指定用户未关注公众号"));
        }
    }


    private void sendLiveMessage(List<WxSubscribeUser> wxSubscribeUsers, LiveTemplateDTO liveTemplateDTO) {
        LiveRoomPO roomPO = liveRoomService.findById(liveTemplateDTO.getRoomId());
        if (roomPO == null) {
            return;
        }
        wxSubscribeUsers.forEach(item -> {
            this.switchSend(liveTemplateDTO, item);
        });
    }


    private void switchSend(LiveTemplateDTO liveTemplateDTO, WxSubscribeUser wxSubscribeUser) {
        switch (liveTemplateDTO.getTemplateMessageType()) {
            case LIVE_SUCCESS:
                threadPoolTaskExecutor.execute(() -> this.sendLiveMessage(wxSubscribeUser, liveTemplateDTO));
                break;
            case SERVICE_START://服务即将开始通知
                threadPoolTaskExecutor.execute(() -> this.sendLiveMessage2(wxSubscribeUser, liveTemplateDTO));
                break;
            case SERVICE_START2:
                threadPoolTaskExecutor.execute(() -> this.sendLiveMessage4(wxSubscribeUser, liveTemplateDTO));
                break;
            case SERVICE_START3:
                threadPoolTaskExecutor.execute(() -> this.sendLiveMessage3(wxSubscribeUser, liveTemplateDTO));
                break;
            default:
                break;
        }
    }

    /**
     * 预约拍卖开始提醒
     *
     * @param item
     * @param liveTemplateDTO
     */
    private void sendLiveMessage(WxSubscribeUser item, LiveTemplateDTO liveTemplateDTO) {
        try {
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue(liveTemplateDTO.getFirst());
            data.add(firstData);
            //拍卖名称
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(liveTemplateDTO.getLiveName());
            data.add(keyword1);
            //开拍时间
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(liveTemplateDTO.getTime());
            data.add(keyword2);

            WxMpTemplateData remark = new WxMpTemplateData();
            remark.setName("remark");
            remark.setValue(liveTemplateDTO.getRemark());
            data.add(remark);
            WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram();
            miniProgram.setPagePath("subPages/live/room/room?roomId=" + liveTemplateDTO.getRoomId());
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.LIVE_SUCCESS.getDesc())
                    .toUser(item.getOpenId())
                    .data(data)
                    .miniProgram(miniProgram)
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {

        }
    }

    /**
     * 服务即将开始通知
     *
     * @param item
     * @param liveTemplateDTO
     */
    private void sendLiveMessage2(WxSubscribeUser item, LiveTemplateDTO liveTemplateDTO) {
        try {
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue(liveTemplateDTO.getFirst());
            data.add(firstData);
            // 项目
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(liveTemplateDTO.getLiveName());
            data.add(keyword1);
            //开始时间
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(liveTemplateDTO.getTime());
            data.add(keyword2);

            //服务人员
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue(liveTemplateDTO.getDirectorName());
            data.add(keyword3);

            WxMpTemplateData keyword4 = new WxMpTemplateData();
            keyword4.setName("keyword4");
            keyword4.setValue(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            data.add(keyword4);
            //备注
            WxMpTemplateData remark = new WxMpTemplateData();
            remark.setName("remark");
            remark.setValue(liveTemplateDTO.getRemark());
            data.add(remark);


            WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram();
            miniProgram.setPagePath("subPages/live/room/room?roomId=" + liveTemplateDTO.getRoomId());
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.SERVICE_START.getDesc())
                    .toUser(item.getOpenId())
                    .data(data)
                    .miniProgram(miniProgram)
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {

        }
    }

    /**
     * 服务开始通知
     *
     * @param item
     * @param liveTemplateDTO
     */
    private void sendLiveMessage3(WxSubscribeUser item, LiveTemplateDTO liveTemplateDTO) {
        try {
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue(liveTemplateDTO.getFirst());
            data.add(firstData);
            /**
             *  服务
             */
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(liveTemplateDTO.getLiveName());
            data.add(keyword1);
            /**
             * 老师
             */
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(liveTemplateDTO.getDirectorName());
            data.add(keyword2);
            /**
             * 订单号
             */
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")));
            data.add(keyword3);
            //备注
            WxMpTemplateData remark = new WxMpTemplateData();
            remark.setName("remark");
            remark.setValue(liveTemplateDTO.getRemark());
            data.add(remark);
            WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram();
            miniProgram.setPagePath("subPages/live/room/room?roomId=" + liveTemplateDTO.getRoomId());
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.SERVICE_START3.getDesc())
                    .toUser(item.getOpenId())
                    .data(data)
                    .miniProgram(miniProgram)
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {

        }
    }


    /**
     * 预约服务开始通知
     *
     * @param item
     * @param liveTemplateDTO
     */
    private void sendLiveMessage4(WxSubscribeUser item, LiveTemplateDTO liveTemplateDTO) {
        try {
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue(liveTemplateDTO.getFirst());
            data.add(firstData);
            //服务时间
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(liveTemplateDTO.getTime());
            data.add(keyword1);
            //服务预估时长
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(liveTemplateDTO.getDuration());
            data.add(keyword2);
            //服务类型
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue("直播");
            data.add(keyword3);

            //服务类型
            WxMpTemplateData keyword4 = new WxMpTemplateData();
            keyword4.setName("keyword4");
            keyword4.setValue(liveTemplateDTO.getDirectorName());
            data.add(keyword4);

            WxMpTemplateData remark = new WxMpTemplateData();
            remark.setName("remark");
            remark.setValue(liveTemplateDTO.getRemark());
            data.add(remark);
            WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram();
            miniProgram.setPagePath("subPages/live/room/room?roomId=" + liveTemplateDTO.getRoomId());
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.SERVICE_START2.getDesc())
                    .toUser(item.getOpenId())
                    .data(data)
                    .miniProgram(miniProgram)
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {

        }
    }

    @Override
    public void sendSubscribeSuccessMessage(Long userId, boolean redPacket) {
        WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUserId(userId);
        if (wxSubscribeUser == null) {
            return;
        }
        sendSubscribeSuccessMessage(wxSubscribeUser, redPacket);

    }

    /**
     * 关注成功通知
     *
     * @param unionId
     */
    @Override
    public void sendSubscribeSuccessMessage(String unionId) {
        WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUnionId(unionId);
        if (wxSubscribeUser == null) {
            return;
        }
        sendSubscribeSuccessMessage(wxSubscribeUser, false);
    }

    /**
     * 关注成功通知
     *
     * @param wxSubscribeUser
     */

    private void sendSubscribeSuccessMessage(WxSubscribeUser wxSubscribeUser, boolean redPacket) {
        try {
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue("恭喜您关注成功");
            data.add(firstData);
            //会员昵称
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(wxSubscribeUser.getNickName());
            data.add(keyword1);
            //关注时间
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            data.add(keyword2);
            WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram();
//            miniProgram.setPagePath("pages/index/index?redPacket=" + (redPacket ? 1 : 0));
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.SUBSCRIBE_SUCCESS.getDesc())
                    .toUser(wxSubscribeUser.getOpenId())
                    .data(data)
                    .miniProgram(miniProgram)
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {


        }
    }

    /**
     * 发货通知
     *
     * @param dto
     */
    @Override
    public void deliverSuccessMessage(DeliverTemplateDTO dto) {
        try {
            WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUserId(dto.getUserId());
            if (wxSubscribeUser == null) {
                return;
            }
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue("您好，您的订单已发货！");
            data.add(firstData);
            //物流单号
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(dto.getExpressNo());
            data.add(keyword1);
            //物流公司
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(dto.getExpressCom());
            data.add(keyword2);
            //发货时间
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            data.add(keyword3);
            //收货人信息
            WxMpTemplateData keyword4 = new WxMpTemplateData();
            keyword4.setName("keyword4");
            keyword4.setValue(dto.getReceivingInfo().toName());
            data.add(keyword4);


            //收货地址
            WxMpTemplateData keyword5 = new WxMpTemplateData();
            keyword5.setName("keyword5");
            keyword5.setValue(dto.getReceivingInfo().fullAddress());
            data.add(keyword5);

            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.DELIVER_SUCCESS.getDesc())
                    .toUser(wxSubscribeUser.getOpenId())
                    .data(data)
                    .miniProgram(getMiniProgram())
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {

        }
    }

    private WxMpTemplateMessage.MiniProgram getMiniProgram() {
        WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
        miniProgram.setPagePath("pages/index/index");
        miniProgram.setAppid(weChatConfig.getMiniAppId());
        return miniProgram;
    }


    /**
     * 用户下单成功通知
     *
     * @param dto
     */
    @Override
    public void createOrderSuccessMessage(UserCreateOrderTemplateDTO dto) {
        try {
            WxSubscribeUser wxSubscribeUser = wxSubscribeUserService.findByUserId(dto.getUserId());
            if (wxSubscribeUser == null) {
                return;
            }
            List<WxMpTemplateData> data = new ArrayList<>();
            WxMpTemplateData firstData = new WxMpTemplateData();
            firstData.setName("first");
            firstData.setValue("您好，您有一个订单。");
            data.add(firstData);
            //订单号
            WxMpTemplateData keyword1 = new WxMpTemplateData();
            keyword1.setName("keyword1");
            keyword1.setValue(dto.getOrderId());
            data.add(keyword1);
            //下单时间：
            WxMpTemplateData keyword2 = new WxMpTemplateData();
            keyword2.setName("keyword2");
            keyword2.setValue(dto.getCreateTime());
            data.add(keyword2);
            //收货人
            WxMpTemplateData keyword3 = new WxMpTemplateData();
            keyword3.setName("keyword3");
            keyword3.setValue(dto.getReceivingInfo().getUserName());
            data.add(keyword3);
            //收货人电话
            WxMpTemplateData keyword4 = new WxMpTemplateData();
            keyword4.setName("keyword4");
            keyword4.setValue(dto.getReceivingInfo().getTelNumber());
            data.add(keyword4);
            //收货地址
            WxMpTemplateData keyword5 = new WxMpTemplateData();
            keyword5.setName("keyword5");
            keyword5.setValue(dto.getReceivingInfo().fullAddress());
            data.add(keyword5);

            WxMpTemplateData remark = new WxMpTemplateData();
            remark.setName("remark");
            remark.setValue(StringUtils.isEmpty(dto.getRemark()) ? "请及时处理!" : dto.getRemark());
            data.add(remark);

            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .templateId(WxTemplateMessageType.USER_CREATE_ORDER.getDesc())
                    .toUser(wxSubscribeUser.getOpenId())
                    .data(data)
                    .miniProgram(getMiniProgram())
                    .build();
            templateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception ignored) {


        }
    }


    @Override
    public long subscribeCount() {
        return wxSubscribeUserService.count();
    }

    @Override
    public long countBySubscribeIsTrue() {
        return wxSubscribeUserService.countBySubscribeIsTrue();
    }
}
